home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
LSD Docs
/
LSD Docs.iso
/
FILEZ
/
lsd15.dms
/
lsd15.adf
/
Ctutorial1.doc.pp
/
Ctutorial1.doc
Wrap
Text File
|
1991-02-19
|
15KB
|
398 lines
ALL AT C - ANOTHER C TUTORIAL
By Andy P++
Do you want to learn to program in C? Or maybe you would
like to understand the Intuition Reference manual? Or
perhaps you are just curious about why the gurus at
Commodore decided it would be a "good thing" to use C for
major parts of the software development for the Amiga.
Then read on.
In this series of articles I hope to introduce all the
major features of C in the context of the Amiga. I assume
that most readers are familiar with at least some form of
programming... even BASIC!
What is C?
Wow! the tricky stuff first. Well, C is the third
letter of the alphabet (our alphabet anyway), but
it is also a name for a programming language. The
language was developed by a small team at Bell
Laboratories. It was created in response to a need
for a language to implement a new operating system,
UNIX.
The language itself was based on a previous
language developed by Ken Thompson in 1970 called B
(hence C... now you know!). B itself owed a lot
to a previous language, BCPL, developed at
Cambridge University in 1967 by Martin Richards.
BCPL stands for Basic CPL (Combined Programming
Language). It is a curious coincidence that, apart
from assembler, the Amigas system software was all
written either in C or BCPL!
OK, but what makes C different from BASIC or assembler?
Lots, but it may help to categorise C as a low-
level language, some have even said a structured
assembler.
BASIC is a much higher level language in the sense
that the user is much more insulated from the
hardware. You BASIC programmers out there (there
are a few left I've been told) are going to have a
much harder time with C than those of you who have
hacked it at the machine level.
Another thing that distinguishes C from BASIC is
that C is almost exclusively compiled. That is
that the program is written first, then translated
to machine code, then run. I say almost
exclusively since I have seen interpreted C
advertised... this seems a case of the worst of
both worlds!
Although closer in spirit to assembler, C is more
of a symbolic language, representing basic
operations in a (nearly) portable way.
OK, Quit the bovine excrement, show us a program
Alright, you asked for it...
main()
{
printf( "Hello world\n");
}
That was a complete program to output the message
'Hello world' followed by a newline to the screen.
To BASIC boys, yes I know it's a bit verbose, to
assembler hackers, yes I know it's a bit brief.
Although easy to write you will go through 7 kinds
of hell trying to compile and run this. It is a
characteristic of this type of programming (as
opposed to BASIC) that a short program is nearly as
tricky as a medium sized one.
Let me try to explain the elements of this "simple"
program.
The word "main()" introduces the start of the
program, it says "this is the first thing to do".
Later I will explain about functions, and the
meaning of the empty brackets should become clear.
The curly brackets "{" and "}" are used to collect
together a set of things, in this case a set of
"statements" (equivalent to lines of basic code, or
lines of assembler).
The only statement in this program is:
printf("Hello World\n");
This says print the text 'Hello world' followed by
a newline ( '\n' is C-speak for a newline).
Most impressive, but there must be more
Well yes, but to explain much more I will have to
go through a few fundamentals of C. At this point
things will probably seem to be a bit disconnected
but I will try to show an example at the end to
draw the threads together.
Data types
C can handle various sorts of data. The principle
simple types are integers (0,1,2 etc, even -1, -2
and so on if you can handle that), characters ( A,
B, C and so on) and floating point numbers (24.678,
0.00045, and many others). These are the basic
sorts of thing that C deals with, and it has a name
for each of them.
There are other types but they are either
variations on a theme (for example signed or
unsigned numbers), or collections of the simple
types (arrays etc.).
In common with assembler, C insists that the person
writing the program tells the compiler about the
data used, its name and its type. Such named
pieces of data are called "variables", each of
which can contain a range of values determined by
the type.
The predefined simple types are:
TYPE DESCRIPTION RANGE
int signed integers -2147483648 to
2147483647
char a character or byte -128 to 127
float a "real" number +/-10E-37 to
+/-10E+38
A few explanations here...
Characters are represented by a small number
corresponding to the ASCII code, eg 'A' is 65.
For the assembler folks, an int is held in 32 bits,
a char in 8 bits and a float in 32 bits.
Until further notice I will ignore floats, as in
many years of programming I have very rarely needed
them.
Given these types, if you want to name a variable
you simply precede the name you want to use with
the name of the type, for example:
int a;
Says the variable 'a' is an integer. C allows
quite a lot of flexibility in naming variables,
lower case, upper case, numbers and underscores,
although names must start with a letter or
underscore.
So:
fred, Quite_A_Long_Name, A12343, _43
are all OK names.
1Henry, 128, &fred, xy#z
would all be rejected.
Statements
As well as data, a complete program uses statements
to tell the computer what to do.
In C there are a range of statement types, we
introduce a couple here.
Assignment:
To change the value of a variable we usually
use an assignment statement. This uses the
equals sign. Assume we have a variable called
'nissan' that is of type 'int', that is it can
contain integers. Then to put the value 4096
in it we use the statement:
nissan = 4096;
The semicolon says, "this is the end of this
statement".
What comes after the '=' sign does not have to
be a single thing, it could be an expression:
nissan = 4096 + 17;
or even reference another variable, say
'mitsubishi':
nissan = 4096 - mitsubishi;
While loop:
The simplest loop in C is the "while" loop. It
allows a statement or group of statements to be
repeated while some condition is true.
This looks like:
while( condition)
statement;
Or if we want to loop through more than one
statement use the curly brackets:
while( condition)
{
statement1;
statement2;
}
Comments
To help make C code more readable (some would say
"less unreadable"!) comments may be
interspersed with the code at most places where
a space could be used.
A comment is distinguished by being enclosed in
comment brackets, /* .... */. The compiler
ignores comments entirely, and unlike some
interpreted languages comments do not slow
down, or make bigger, your program so feel free
to express yourself.
A more complete example
Using what we now know, lets write a simple program
to print out the numbers 1 to 5 and the cubes
of these numbers.
main() /* Remember, this says start here */
{
/* Declare an integer variable */
int a_number;
/* And another for its cube */
int cube;
/* Initialise a number */
a_number = 1;
while ( a_number <= 5)
{
/* Calculate the cube */
cube = a_number * a_number * a_number;
/* And print the result */
printf("%d cubed is %d\n", a_number, cube);
/* Go on to the next number */
a_number = a_number + 1;
}
}
Quick word of explanation on the "printf" line.
"printf" is the nearest equivalent C has to BASICs
PRINT command. It is rather more ugly to look at
but can do very similar (and in some cases more
sophisticated) things. Rather than the simple
print of a string we did before, now we are
printing numbers inside a string. Wherever the
"%d" is found, the next number in the list that
follows is displayed.
The output of that program will therefore look
like:
1 cubed is 1
2 cubed is 8
3 cubed is 27
4 cubed is 64
5 cubed is 125
That seemed a bit windy, there will be those of you
out there saying, "Yes, but I thought C was terse
and obscure". You would of course be right in a
sense as it largely depends on the programmer.
Putting my C-hacker hat on we can rewrite the
previous program as:
main()
{
int i=0;
while( ++i < 6)
printf( "%d cubed is %d\n", i, i*i*i);
}
This introduces only one really new concept (apart
from the fact that C programmers take an odd
pleasure in being needlessly obscure) and that is
the increment operator, the double plus sign.
This operator is worthy of a place in the "black
museum" of programming. Its advantage is in
producing very terse programs that are easily
translated to quite terse object programs. Its
disadvantage is that badly used it can make a
program very difficult to understand.
The effect of the ++ operator is twofold. When
placed in front of a variable it first adds one to
the variable, and then returns that incremented
value.
Assembler programmers will understand the ++
operator as being very similar to an INC
instruction. Most high level languages do not have
a similar concept so the C statement:
charlie = ++fred;
would in most ordinary languages be something
like:
fred = fred + 1;
charlie = fred;
Note that both examples there were in fact valid C
and if you don't like them you can always avoid the
use of the ++ operator. Unfortunately you will
probably need to read code using it.
Before I wrap up this first lesson (watch out K&R,
here I come!) lets just go through the full list of
simple data types (I previously simplified things).
signed char A character in the range
-128 to +127, also often
known simply as "char"
unsigned char A character in the range 0
to 255.
signed short int An integer in the range
-32768 to +32767.
unsigned short int An integer in the range 0
to 65535.
signed int An integer in the range
2147483648 to 2147483647,
also known simply as
"int".
unsigned int An integer in the range 0
to 4294987295.
signed long int As per "signed int".
unsigned long int As per "unsigned int".
float A floating point number in
the range +/-10E-37 to +/-
10E+38. A low precision
floating point number.
double A floating point number in
the range +/-10E-307 to
+/-10E+308.
A high precision floating
point number.
pointer A memory address in the
range 0 to 0xFFFFFFFF
(that was a hex number, 32
bits worth).
That was all the possibilities for the Lattice
compiler. All halfway decent C compilers support
the same set of simple types although the precise
ranges and what "int" and "char" default to may
vary. You can expect all compilers for the 68000
(which the Amiga uses) would have a similar set of
ranges and defaults.
Well, thats all folks for lesson 1. In lesson 2 we
will ponder the mysteries of the full range of C
operators, complex data types and pointers. If you
can stick with it for that long you deserve the C
order of merit.
End.